package eu.hellek.gba.server.dao; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import com.googlecode.objectify.Key; import com.googlecode.objectify.Objectify; import com.googlecode.objectify.ObjectifyService; import com.googlecode.objectify.Query; import com.googlecode.objectify.util.DAOBase; import eu.hellek.gba.model.Line; import eu.hellek.gba.model.PQA; import eu.hellek.gba.model.PlanQuadrat; import eu.hellek.gba.model.Point; import eu.hellek.gba.model.TrainNode; import eu.hellek.gba.server.utils.Utils; public class ManagementDao extends DAOBase { private static ManagementDao instance; @SuppressWarnings("unused") private static Dao daoInstance; private static String location = "ManagementDao"; public static synchronized ManagementDao getInstance() { if(instance == null) { daoInstance = Dao.getInstance(); instance = new ManagementDao(); } return instance; } public Key<Line> addLine(Line l, Objectify ofy) { return ofy.put(l); } public void setPointsForLine(Line l, List<Point> pointsList, Objectify ofy) { if(l.getId() == 0) { System.err.println("error: line-id = 0"); } Key<Line> lineKey = new Key<Line>(Line.class, l.getId()); for(Point p : pointsList) { p.setOwner(lineKey); } safePoints(pointsList, ofy); } public void safePoints(List<Point> pointsList, Objectify ofy) { ofy.put(pointsList); } public synchronized void addOrUpdatePlanQuadrats(Set<String> geoCells, HashMap<String,Integer> directGeoCells, Line l, HashMap<String,Boolean> ignoreCells, HashMap<String,Boolean> twowayCells, boolean isMainLine) { String functionName = "addOrUpdatePlanQuadrats()"; Objectify ofy1 = ObjectifyService.beginTransaction(); Iterator<String> iter1 = geoCells.iterator(); try { while(iter1.hasNext()) { PlanQuadrat pq = null; String geoCell = iter1.next(); /* Query<PlanQuadrat> q = ofy.query(PlanQuadrat.class).filter("geoCell", geoCell); PlanQuadrat res = q.get();*/ PlanQuadrat res = ofy1.find(new Key<PlanQuadrat>(Dao.getRootEntityBus(), PlanQuadrat.class, geoCell)); if(res != null) { pq = res; } else { pq = new PlanQuadrat(geoCell, Dao.getRootEntityBus()); } if(directGeoCells.containsKey(geoCell)) { Key<Line> lineKey = new Key<Line>(Line.class, l.getId()); boolean twoway = false; if(twowayCells.containsKey(geoCell)) { twoway = true; } pq.addDirectLineKey(lineKey, directGeoCells.get(geoCell)); if(isMainLine) { pq.addMainLineKey(lineKey, ignoreCells.get(geoCell), twoway); } } ofy1.put(pq); } ofy1.getTxn().commit(); } finally { if (ofy1.getTxn().isActive()) { ofy1.getTxn().rollback(); removeLine(l, ObjectifyService.begin()); Logger.getLogger(location).log(Level.SEVERE, functionName + ": Transaction failed for Line: " + l); } } Objectify ofy2 = ObjectifyService.beginTransaction(); Iterator<String> iter2 = geoCells.iterator(); try { while(iter2.hasNext()) { String geoCell = iter2.next(); if(directGeoCells.containsKey(geoCell) && isMainLine) { PQA pq = null; PQA res = ofy2.find(new Key<PQA>(Dao.getRootEntityPQA(), PQA.class, geoCell)); if(res != null) { pq = res; } else { pq = new PQA(geoCell, Dao.getRootEntityPQA()); } Key<Line> lineKey = new Key<Line>(Line.class, l.getId()); boolean twoway = false; if(twowayCells.containsKey(geoCell)) { twoway = true; } pq.addLine(lineKey, directGeoCells.get(geoCell), ignoreCells.get(geoCell), twoway); ofy2.put(pq); } } ofy2.getTxn().commit(); } finally { if (ofy2.getTxn().isActive()) { ofy2.getTxn().rollback(); removeLine(l, ObjectifyService.begin()); Logger.getLogger(location).log(Level.SEVERE, functionName + ": Transaction failed for Line: " + l); } } } public synchronized Key<TrainNode> addTrainNode(TrainNode tn) { String functionName = "addTrainNode()"; Key<TrainNode> resKey = null; Objectify ofy = ObjectifyService.beginTransaction(); try { Query<TrainNode> q = ofy.query(TrainNode.class).filter("uniqueName", tn.getUniqueName()).ancestor(Dao.getRootEntityTrain()); List<TrainNode> samestation = q.list(); if(samestation.size() > 0) { if(Utils.distanceBetweenGeoCells(samestation.get(0).getGeoCell(), tn.getGeoCell()) <= 10) { tn.setGeoCell(samestation.get(0).getGeoCell()); Logger.getLogger(location).log(Level.WARNING, functionName + ": joined/moved station " + tn.getUniqueName() + " for " + tn.getLineKey()); } else { Logger.getLogger(location).log(Level.SEVERE, functionName + ": did not move station " + tn.getUniqueName() + " for " + tn.getLineKey() + " because distance is too big: " + Utils.distanceBetweenGeoCells(samestation.get(0).getGeoCell(), tn.getGeoCell())); } } resKey = ofy.put(tn); ofy.getTxn().commit(); } finally { if (ofy.getTxn().isActive()) { ofy.getTxn().rollback(); removeLine(Dao.getInstance().getLineByKey(tn.getLineKey(), ObjectifyService.begin()), ObjectifyService.begin()); Logger.getLogger(location).log(Level.SEVERE, functionName + ": Transaction failed for Line: " + tn.getLineKey()); } } return resKey; } public synchronized void updateTrainNode(TrainNode tn) { String functionName = "updateTrainNode"; Objectify ofy = ObjectifyService.beginTransaction(); try { ofy.put(tn); ofy.getTxn().commit(); } finally { if (ofy.getTxn().isActive()) { ofy.getTxn().rollback(); removeLine(Dao.getInstance().getLineByKey(tn.getLineKey(), ObjectifyService.begin()), ObjectifyService.begin()); Logger.getLogger(location).log(Level.SEVERE, functionName + ": Transaction failed for Line: " + tn.getLineKey()); } } } private synchronized void deleteLineFromPlanQuadrats(Line l) { Key<Line> lineKey = new Key<Line>(Line.class, l.getId()); String functionName = "deleteLineFromPlanQuadrats"; Objectify ofy1 = ObjectifyService.beginTransaction(); try { Query<PlanQuadrat> q = ofy1.query(PlanQuadrat.class).filter("directLineKeys", lineKey).ancestor(Dao.getRootEntityBus()); List<PlanQuadrat> pqs = q.list(); for(PlanQuadrat pq : pqs) { pq.removeLine(lineKey); if(pq.getDirectLineKeys().size() > 0) { ofy1.put(pq); } else { ofy1.delete(pq); } } ofy1.getTxn().commit(); } finally { if (ofy1.getTxn().isActive()) { ofy1.getTxn().rollback(); Logger.getLogger(location).log(Level.SEVERE, functionName + ": Transaction failed for Line: " + l); } } Objectify ofy2 = ObjectifyService.beginTransaction(); try { Query<PQA> q = ofy2.query(PQA.class).filter("lineKeys", lineKey).ancestor(Dao.getRootEntityPQA()); List<PQA> pqs = q.list(); for(PQA pq : pqs) { pq.removeLine(lineKey); if(pq.getLineKeys().size() > 0) { ofy2.put(pq); } else { ofy2.delete(pq); } } ofy2.getTxn().commit(); } finally { if (ofy2.getTxn().isActive()) { ofy2.getTxn().rollback(); Logger.getLogger(location).log(Level.SEVERE, functionName + ": Transaction failed for Line: " + l); } } } public synchronized void removeLine(Line l, Objectify ofy) { deleteLineFromPlanQuadrats(l); deletePointsForLine(l, ofy); deleteTrainNodesForLine(l, ofy); ofy.delete(l); } private synchronized void deletePointsForLine(Line l, Objectify ofy) { Query<Point> q = ofy.query(Point.class).ancestor(l); List<Key<Point>> keys = q.listKeys(); ofy.delete(keys); } private synchronized void deleteTrainNodesForLine(Line l, Objectify ofy) { Query<TrainNode> q = ofy.query(TrainNode.class).filter("lineKey", new Key<Line>(Line.class, l.getId())); List<Key<TrainNode>> keys = q.listKeys(); ofy.delete(keys); } public List<Line> getLines(Objectify ofy) { Query<Line> q = ofy.query(Line.class).order("linenum"); List<Line> lines = q.list(); return lines; } public synchronized boolean checkIfLineExists(Line l, Objectify ofy) { Query<Line> q = ofy.query(Line.class).filter("linenum", l.getLinenum()).filter("ramal", l.getRamal()).filter("type", l.getType()); List<Line> lines = q.list(); if(lines.size() > 0) { return true; } else { return false; } } public List<Key<Line>> getAllTrainKeys(Objectify ofy) { Query<Line> q = ofy.query(Line.class).filter("type >", 10); List<Key<Line>> keys = q.listKeys(); return keys; } }